import React, { useState, useEffect, useRef, useCallback } from 'react';
import './Dashboard.css';

// 定义分类维度类型
type ClassificationDimension = '分类' | '性味归经' | '功能主治' | '毒性副作用';

// 定义属性维度类型
type PropertyDimension = '性' | '味' | '归经' | '功效' | '毒性';

// 定义药材类型
interface Herb {
  id: string;
  name: string;
  category: string;
  properties: {
    性: string;
    味: string[];
  };
  functions: string[];
  toxicity: boolean;
  description?: string;
  commonUsage?: boolean;
  origin?: [number, number];
  historicalOrigins?: {
    [key in HistoricalPeriod]?: [number, number] | null;
  };
  versionChanges?: {
    [key: string]: string;
  };
}

// 定义搜索筛选选项类型
interface FilterOptions {
  keyword: string;
  category: string;
  view: ViewType;
}

// 分类树节点展开状态记录
interface ExpandedState {
  [key: string]: boolean;
}

// 新增关联关系类型
interface HerbRelation {
  source: string;
  target: string;
  strength: number;
  type: string;
}

// 新增关系图节点类型
interface NetworkNode {
  id: string;
  name: string;
  category: string;
  group?: number;
  value?: number;
  x?: number;
  y?: number;
  vx?: number;
  vy?: number;
}

// 新增关系图连接类型
interface NetworkLink {
  source: string;
  target: string;
  strength: number;
  type: string;
}

// 新增历史时期类型
type HistoricalPeriod = '先秦' | '汉代' | '魏晋南北朝' | '隋唐' | '宋元' | '明代' | '清代' | '现代';

// 新增地图视图模式类型
type MapViewMode = 'origin' | 'distribution' | 'heatmap' | 'comparison';

// 视图类型
type ViewType = 'overview' | 'classification' | 'properties' | 'relations' | 'geographic' | 'textual';

// 新增文本分析相关类型
type TextAnalysisMode = 'wordcloud' | 'historical' | 'sentiment' | 'evolution';
type TimePeriod = '古代' | '中古' | '近代' | '现代';

// 文本情感类型
type SentimentType = '正面' | '中性' | '负面';

interface DashboardProps {
  initialView?: ViewType;
}

// 确保主题演化数据总是有默认值防止undefined错误
const DEFAULT_THEME_DATA = [
  { theme: '药性理论', periods: { '古代': 50, '中古': 50, '近代': 50, '现代': 50 } },
  { theme: '治疗应用', periods: { '古代': 50, '中古': 50, '近代': 50, '现代': 50 } },
  { theme: '炮制方法', periods: { '古代': 50, '中古': 50, '近代': 50, '现代': 50 } },
  { theme: '药理研究', periods: { '古代': 50, '中古': 50, '近代': 50, '现代': 50 } },
  { theme: '临床效果', periods: { '古代': 50, '中古': 50, '近代': 50, '现代': 50 } }
];

export const Dashboard: React.FC<DashboardProps> = ({ initialView = 'overview' }) => {
  const [activeView, setActiveView] = useState<ViewType>(initialView);
  const [classificationDimension, setClassificationDimension] = useState<ClassificationDimension>('分类');
  const [filterOptions, setFilterOptions] = useState<FilterOptions>({
    keyword: '',
    category: '',
    view: 'overview'
  });
  const [herbs, setHerbs] = useState<Herb[]>([]);
  const [categories, setCategories] = useState<string[]>([]);
  const [selectedHerb, setSelectedHerb] = useState<Herb | null>(null);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [categoryStats, setCategoryStats] = useState<{[key: string]: number}>({});
  const [natureStats, setNatureStats] = useState<{[key: string]: number}>({});
  const [tasteStats, setTasteStats] = useState<{[key: string]: number}>({});
  const [functionStats, setFunctionStats] = useState<{[key: string]: number}>({});
  const [expandedCategories, setExpandedCategories] = useState<ExpandedState>({});
  const [selectedHerbs, setSelectedHerbs] = useState<Herb[]>([]);
  const [propertyDimensions, setPropertyDimensions] = useState<PropertyDimension[]>(['性', '味', '功效']);
  const [comparisonMode, setComparisonMode] = useState<'radar' | 'scatter'>('radar');
  
  // 新增状态变量 - 关联网络界面
  const [relations, setRelations] = useState<HerbRelation[]>([]);
  const [networkNodes, setNetworkNodes] = useState<NetworkNode[]>([]);
  const [networkLinks, setNetworkLinks] = useState<NetworkLink[]>([]);
  const [strengthThreshold, setStrengthThreshold] = useState<number>(0.3);
  const [centerHerb, setCenterHerb] = useState<string>('');
  const [clusterAlgorithm, setClusterAlgorithm] = useState<string>('louvain');
  const [showLabels, setShowLabels] = useState<boolean>(true);
  const [selectedNode, setSelectedNode] = useState<string>('');
  const [networkSimulation, setNetworkSimulation] = useState<any>(null);
  
  // 新增地理与历史数据界面的状态变量
  const [mapViewMode, setMapViewMode] = useState<MapViewMode>('origin');
  const [historicalPeriod, setHistoricalPeriod] = useState<HistoricalPeriod>('明代');
  const [compareVersion, setCompareVersion] = useState<string>('初刻本');
  const [herbLocations, setHerbLocations] = useState<{[key: string]: [number, number]}>({});
  const [regionHeatmap, setRegionHeatmap] = useState<{[key: string]: number}>({});
  const [selectedRegion, setSelectedRegion] = useState<string>('');
  const [regionHerbs, setRegionHerbs] = useState<Herb[]>([]);
  const [mapZoom, setMapZoom] = useState<number>(5);
  const [mapCenter, setMapCenter] = useState<[number, number]>([104, 35]); // 中国大致中心
  
  // 文本分析相关状态
  const [textAnalysisMode, setTextAnalysisMode] = useState<TextAnalysisMode>('wordcloud');
  const [selectedHerbForText, setSelectedHerbForText] = useState<string>('');
  const [searchText, setSearchText] = useState<string>('');
  const [wordCloudData, setWordCloudData] = useState<{text: string, value: number}[]>([]);
  const [historicalQuotes, setHistoricalQuotes] = useState<{period: string, quote: string, source: string}[]>([]);
  const [sentimentData, setSentimentData] = useState<{period: string, positive: number, neutral: number, negative: number}[]>([]);
  const [themeEvolutionData, setThemeEvolutionData] = useState<{theme: string, periods: {[key in TimePeriod]?: number}}[]>([]);
  
  const textAnalysisRef = useRef<HTMLDivElement>(null);
  
  // DOM引用，用于图表绘制
  const categoryChartRef = useRef<HTMLDivElement>(null);
  const pieChartRef = useRef<HTMLDivElement>(null);
  const networkRef = useRef<HTMLDivElement>(null);
  const mapRef = useRef<HTMLDivElement>(null);
  
  // 加载药材数据
  useEffect(() => {
    const loadData = async () => {
      try {
        setIsLoading(true);
        
        // 加载药材数据 - 修改为加载扩展数据集
        const herbsResponse = await fetch('/src/data/herbs_extended.json');
        const herbsData = await herbsResponse.json();
        const herbsList = Object.values(herbsData) as Herb[];
        setHerbs(herbsList);
        
        // 提取所有分类
        const allCategories = [...new Set(herbsList.map((herb: Herb) => herb.category))];
        setCategories(allCategories);
        
        // 计算统计数据
        calculateStats(herbsList);

        // 加载药材关联数据
        try {
          const relationsResponse = await fetch('/src/data/relations.csv');
          const relationsText = await relationsResponse.text();
          const relationsList = parseRelationsCSV(relationsText);
          setRelations(relationsList);
        } catch (relationError) {
          console.error('Failed to load relations data:', relationError);
          // 生成随机关联数据作为替代
          const randomRelations = generateRandomRelations(herbsList);
          setRelations(randomRelations);
        }
        
        // 提取药材地理位置数据
        const locationData: {[key: string]: [number, number]} = {};
        herbsList.forEach(herb => {
          if ('origin' in herb && Array.isArray(herb.origin) && herb.origin.length === 2) {
            locationData[herb.id] = herb.origin as [number, number];
          }
        });
        setHerbLocations(locationData);
        
        // 生成区域热力图数据
        const regions = ['华北', '东北', '华东', '华中', '华南', '西南', '西北'];
        const heatmapData: {[key: string]: number} = {};
        
        // 根据药材产地分布统计各区域数量
        const regionCount: {[key: string]: number} = {
          '华北': 0,
          '东北': 0,
          '华东': 0,
          '华中': 0,
          '华南': 0,
          '西南': 0,
          '西北': 0
        };
        
        // 简单的经纬度到区域的映射（真实应用中可能需要更复杂的地理定位）
        herbsList.forEach(herb => {
          if (herb.origin) {
            const [lng, lat] = herb.origin;
            if (lat > 40) {
              if (lng < 120) regionCount['华北']++;
              else regionCount['东北']++;
            } else if (lat > 35) {
              if (lng < 110) regionCount['西北']++;
              else regionCount['华东']++;
            } else if (lat > 28) {
              if (lng < 110) regionCount['西南']++;
              else regionCount['华中']++;
            } else {
              regionCount['华南']++;
            }
          }
        });
        
        // 将计数转化为热力图数据百分比
        regions.forEach(region => {
          heatmapData[region] = Math.min(100, regionCount[region] * 10);
        });
        
        setRegionHeatmap(heatmapData);
        
        // 生成词云数据
        generateWordCloudData(herbsList);
        
        setIsLoading(false);
      } catch (error) {
        console.error('Failed to load data:', error);
        // 如果扩展数据加载失败，回退到原始数据集
        try {
          const fallbackResponse = await fetch('/src/data/herbs.json');
          const fallbackData = await fallbackResponse.json();
          const fallbackList = Object.values(fallbackData) as Herb[];
          setHerbs(fallbackList);
          
          const allCats = [...new Set(fallbackList.map((herb: Herb) => herb.category))];
          setCategories(allCats);
          
          calculateStats(fallbackList);
        } catch (fallbackError) {
          console.error('Failed to load fallback data:', fallbackError);
        }
        setIsLoading(false);
      }
    };

    loadData();
  }, []);

  // 计算统计数据
  const calculateStats = (herbsList: Herb[]) => {
    // 分类统计
    const catStats: {[key: string]: number} = {};
    herbsList.forEach(herb => {
      catStats[herb.category] = (catStats[herb.category] || 0) + 1;
    });
    setCategoryStats(catStats);
    
    // 药性统计
    const natStats: {[key: string]: number} = {};
    herbsList.forEach(herb => {
      if (herb.properties && herb.properties.性) {
        natStats[herb.properties.性] = (natStats[herb.properties.性] || 0) + 1;
      }
    });
    setNatureStats(natStats);
    
    // 药味统计
    const tastStats: {[key: string]: number} = {};
    herbsList.forEach(herb => {
      if (herb.properties && herb.properties.味) {
        herb.properties.味.forEach(taste => {
          tastStats[taste] = (tastStats[taste] || 0) + 1;
        });
      }
    });
    setTasteStats(tastStats);
    
    // 功能统计
    const funcStats: {[key: string]: number} = {};
    herbsList.forEach(herb => {
      if (herb.functions) {
        herb.functions.forEach(func => {
          funcStats[func] = (funcStats[func] || 0) + 1;
        });
      }
    });
    setFunctionStats(funcStats);
  };

  // 解析CSV关系数据
  const parseRelationsCSV = (csvText: string) => {
    const lines = csvText.split('\n');
    const relations: HerbRelation[] = [];
    
    // 跳过标题行
    for(let i = 1; i < lines.length; i++) {
      const line = lines[i].trim();
      if(!line) continue;
      
      const parts = line.split(',');
      if(parts.length >= 4) {
        relations.push({
          source: parts[0],
          target: parts[1],
          strength: parseFloat(parts[2]),
          type: parts[3]
        });
      }
    }
    
    return relations;
  };

  // 生成随机关联数据（当无法加载实际数据时使用）
  const generateRandomRelations = (herbsList: Herb[]) => {
    const relations: HerbRelation[] = [];
    const relationTypes = ['配伍', '相须', '相使', '相畏', '相杀', '相恶', '相反'];
    
    // 为每个药材生成2-5个随机关联
    herbsList.forEach(herb => {
      const relationCount = Math.floor(Math.random() * 4) + 2; // 2-5个关联
      
      for(let i = 0; i < relationCount; i++) {
        // 随机选择目标药材（不重复）
        let targetIndex;
        do {
          targetIndex = Math.floor(Math.random() * herbsList.length);
        } while(herbsList[targetIndex].id === herb.id);
        
        const target = herbsList[targetIndex];
        const typeIndex = Math.floor(Math.random() * relationTypes.length);
        
        // 生成0.1-1.0之间的随机强度
        const strength = Math.round((Math.random() * 0.9 + 0.1) * 100) / 100;
        
        relations.push({
          source: herb.id,
          target: target.id,
          strength: strength,
          type: relationTypes[typeIndex]
        });
      }
    });
    
    return relations;
  };

  // 处理视图切换
  const handleViewChange = (view: ViewType) => {
    setActiveView(view);
    setFilterOptions(prev => ({ ...prev, view }));
  };

  // 处理分类维度切换
  const handleDimensionChange = (dimension: ClassificationDimension) => {
    setClassificationDimension(dimension);
    setSelectedHerb(null); // 切换维度时清除选中的药材
    setExpandedCategories({}); // 重置展开状态
  };

  // 处理分类的展开/折叠
  const toggleCategoryExpand = useCallback((category: string) => {
    setExpandedCategories(prev => ({
      ...prev,
      [category]: !prev[category]
    }));
  }, []);

  // 处理药材选择
  const handleHerbSelect = (herb: Herb) => {
    setSelectedHerb(herb);
  };

  // 处理关键词搜索
  const handleKeywordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFilterOptions(prev => ({ ...prev, keyword: e.target.value }));
  };

  // 处理分类筛选
  const handleCategoryChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    setFilterOptions(prev => ({ ...prev, category: e.target.value }));
  };

  // 处理药材多选
  const handleHerbMultiSelect = (herb: Herb) => {
    setSelectedHerbs(prev => {
      // 如果已经选中，则移除
      if (prev.some(h => h.id === herb.id)) {
        return prev.filter(h => h.id !== herb.id);
      }
      // 否则添加，但最多选择5个
      else if (prev.length < 5) {
        return [...prev, herb];
      }
      return prev;
    });
  };

  // 处理维度选择
  const handleDimensionToggle = (dimension: PropertyDimension) => {
    setPropertyDimensions(prev => {
      if (prev.includes(dimension)) {
        return prev.filter(d => d !== dimension);
      } else {
        return [...prev, dimension];
      }
    });
  };

  // 处理关系强度阈值变化
  const handleStrengthThresholdChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setStrengthThreshold(parseFloat(e.target.value));
  };

  // 处理中心药材选择变化
  const handleCenterHerbChange = (id: string) => {
    setCenterHerb(id);
  };

  // 处理聚类算法变化
  const handleClusterAlgorithmChange = (algorithm: string) => {
    setClusterAlgorithm(algorithm);
  };

  // 切换节点标签显示
  const toggleLabels = () => {
    setShowLabels(!showLabels);
  };

  // 处理节点选择
  const handleNodeSelect = (nodeId: string) => {
    setSelectedNode(prevId => prevId === nodeId ? '' : nodeId);
  };

  // 构建网络图数据
  useEffect(() => {
    if (relations.length > 0 && herbs.length > 0 && activeView === 'relations') {
      // 转换为Map以便快速查找
      const herbsMap = new Map<string, Herb>();
      herbs.forEach(herb => herbsMap.set(herb.id, herb));
      
      // 初始化节点集合
      const nodesMap = new Map<string, NetworkNode>();
      
      // 构建过滤后的连接
      const filteredLinks: NetworkLink[] = [];
      
      // 根据筛选条件处理关系数据
      relations.forEach(relation => {
        // 检查强度是否高于阈值
        if (relation.strength >= strengthThreshold) {
          // 如果设置了中心药材，则只保留与其相关的连接
          if (centerHerb && centerHerb !== '' && relation.source !== centerHerb && relation.target !== centerHerb) {
            return;
          }
          
          // 添加连接
          filteredLinks.push({
            source: relation.source,
            target: relation.target,
            strength: relation.strength,
            type: relation.type
          });
          
          // 确保相关节点被添加
          if (!nodesMap.has(relation.source) && herbsMap.has(relation.source)) {
            const herb = herbsMap.get(relation.source)!;
            nodesMap.set(relation.source, {
              id: relation.source,
              name: herb.name,
              category: herb.category
            });
          }
          
          if (!nodesMap.has(relation.target) && herbsMap.has(relation.target)) {
            const herb = herbsMap.get(relation.target)!;
            nodesMap.set(relation.target, {
              id: relation.target,
              name: herb.name,
              category: herb.category
            });
          }
        }
      });
      
      // 转换为数组
      const nodes = Array.from(nodesMap.values());
      
      // 简单聚类分析 - 基于类别
      if (clusterAlgorithm === 'category') {
        // 获取所有分类的集合
        const categorySet = new Set<string>();
        nodes.forEach(node => categorySet.add(node.category));
        const categories = Array.from(categorySet);
        
        // 为每个节点分配组号
        nodes.forEach(node => {
          node.group = categories.indexOf(node.category) + 1;
        });
      }
      // 简单聚类分析 - 基于连接度
      else if (clusterAlgorithm === 'degree') {
        // 计算每个节点的连接数
        const degreeMap = new Map<string, number>();
        
        filteredLinks.forEach(link => {
          degreeMap.set(link.source, (degreeMap.get(link.source) || 0) + 1);
          degreeMap.set(link.target, (degreeMap.get(link.target) || 0) + 1);
        });
        
        // 设置每个节点的值和组
        nodes.forEach(node => {
          const degree = degreeMap.get(node.id) || 0;
          node.value = degree;
          
          // 根据连接数分组 (1-3: 组1, 4-6: 组2, 7+: 组3)
          if (degree < 4) node.group = 1;
          else if (degree < 7) node.group = 2;
          else node.group = 3;
        });
      }
      // 洛文社区检测算法 (简化模拟)
      else {
        // 简单模拟洛文算法的结果
        // 在实际应用中应该使用专门的图算法库
        const nodeCount = nodes.length;
        const groupCount = Math.max(3, Math.floor(nodeCount / 10));
        
        nodes.forEach(node => {
          // 随机分配组，但尝试保持相似类别的节点在同一组
          const hash = node.category.charCodeAt(0) + node.name.charCodeAt(0);
          node.group = (hash % groupCount) + 1;
        });
      }
      
      setNetworkNodes(nodes);
      setNetworkLinks(filteredLinks);
    }
  }, [relations, herbs, strengthThreshold, centerHerb, clusterAlgorithm, activeView]);

  // 实现简单的力导向布局
  useEffect(() => {
    if (networkNodes.length > 0 && networkLinks.length > 0 && activeView === 'relations' && networkRef.current) {
      // 停止之前的模拟（如果存在）
      if (networkSimulation) {
        clearInterval(networkSimulation);
      }
      
      // 计算容器尺寸
      const container = networkRef.current;
      const width = container.clientWidth;
      const height = container.clientHeight;
      
      // 初始化节点位置（在中心位置附近随机分布）
      const nodes = networkNodes.map(node => ({
        ...node,
        x: width / 2 + (Math.random() - 0.5) * 200,
        y: height / 2 + (Math.random() - 0.5) * 200,
        vx: 0,
        vy: 0
      }));
      
      // 创建节点映射以便快速查找
      const nodeMap = new Map();
      nodes.forEach(node => nodeMap.set(node.id, node));
      
      // 转换链接，使用实际节点对象
      const links = networkLinks.map(link => ({
        ...link,
        sourceNode: nodeMap.get(link.source),
        targetNode: nodeMap.get(link.target)
      }));
      
      // 力导向布局参数
      const forceParameters = {
        repulsion: 200,      // 节点间斥力
        attraction: 0.05,    // 链接的吸引力
        centerGravity: 0.01, // 向中心的引力
        damping: 0.9,        // 速度衰减因子
        maxSpeed: 5          // 最大速度限制
      };
      
      // 启动力导向布局模拟
      const interval = setInterval(() => {
        // 计算节点间斥力
        nodes.forEach(node1 => {
          nodes.forEach(node2 => {
            if (node1.id !== node2.id) {
              const dx = node2.x - node1.x;
              const dy = node2.y - node1.y;
              const distance = Math.sqrt(dx * dx + dy * dy) || 1;
              
              // 应用斥力（反比于距离的平方）
              const force = forceParameters.repulsion / (distance * distance);
              const fx = (dx / distance) * force;
              const fy = (dy / distance) * force;
              
              node1.vx -= fx;
              node1.vy -= fy;
              node2.vx += fx;
              node2.vy += fy;
            }
          });
        });
        
        // 链接的吸引力
        links.forEach(link => {
          const source = link.sourceNode;
          const target = link.targetNode;
          
          const dx = target.x - source.x;
          const dy = target.y - source.y;
          const distance = Math.sqrt(dx * dx + dy * dy) || 1;
          
          // 应用吸引力（与距离成正比，与关系强度成正比）
          const force = distance * forceParameters.attraction * link.strength;
          const fx = (dx / distance) * force;
          const fy = (dy / distance) * force;
          
          source.vx += fx;
          source.vy += fy;
          target.vx -= fx;
          target.vy -= fy;
        });
        
        // 向中心的引力
        nodes.forEach(node => {
          const dx = width / 2 - node.x;
          const dy = height / 2 - node.y;
          
          node.vx += dx * forceParameters.centerGravity;
          node.vy += dy * forceParameters.centerGravity;
          
          // 应用阻尼（速度衰减）
          node.vx *= forceParameters.damping;
          node.vy *= forceParameters.damping;
          
          // 限制最大速度
          const speed = Math.sqrt(node.vx * node.vx + node.vy * node.vy);
          if (speed > forceParameters.maxSpeed) {
            node.vx = (node.vx / speed) * forceParameters.maxSpeed;
            node.vy = (node.vy / speed) * forceParameters.maxSpeed;
          }
          
          // 更新位置
          node.x += node.vx;
          node.y += node.vy;
          
          // 边界约束 (保持节点在可见区域内)
          const padding = 10;
          const nodeSize = node.value ? 5 + node.value * 2 : 10;
          
          if (node.x < padding + nodeSize) node.x = padding + nodeSize;
          if (node.x > width - padding - nodeSize) node.x = width - padding - nodeSize;
          if (node.y < padding + nodeSize) node.y = padding + nodeSize;
          if (node.y > height - padding - nodeSize) node.y = height - padding - nodeSize;
        });
        
        // 更新图形
        // 我们不能直接操作DOM，所以通过状态更新让React重新渲染
        // 这个简单的解决方案不是最高效的，但对于演示足够了
        setNetworkNodes([...nodes]);
      }, 50); // 每50ms更新一次
      
      // 保存模拟引用以便之后清理
      setNetworkSimulation(interval);
      
      // 组件卸载时清理
      return () => {
        clearInterval(interval);
      };
    }
  }, [networkNodes.length, networkLinks.length, activeView]);

  // 生成饼图
  const renderPieChart = useCallback((data: {[key: string]: number}, colors: string[]) => {
    const total = Object.values(data).reduce((sum, value) => sum + value, 0);
    const sortedEntries = Object.entries(data)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 8); // 增加显示数量到8个
    
    let cumulativePercent = 0;
    
    return (
      <div className="pie-chart-container">
        <div className="pie-chart">
          <div className="pie-segments">
            {sortedEntries.map(([category, value], index) => {
              const percent = (value / total) * 100;
              const startPercent = cumulativePercent;
              cumulativePercent += percent;
              
              // 简化clipPath的实现方式
              const rotation = startPercent * 3.6;
              const angle = percent * 3.6;
              
              return (
                <div
                  key={category}
                  className="pie-segment"
                  style={{
                    backgroundColor: colors[index % colors.length],
                    transform: `rotate(${rotation}deg)`,
                    clipPath: `polygon(0 0, 100% 0, 100% 100%, 0% 100%)`,
                    zIndex: sortedEntries.length - index,
                    opacity: 0.9
                  }}
                  title={`${category}: ${value} (${percent.toFixed(1)}%)`}
                />
              );
            })}
          </div>
        </div>
        <div className="pie-legend">
          {sortedEntries.map(([category, value], index) => (
            <div key={index} className="legend-item">
              <span 
                className="legend-color" 
                style={{backgroundColor: colors[index % colors.length]}}
              ></span>
              <span className="legend-label">{category}</span>
              <span className="legend-value">{value} ({((value / total) * 100).toFixed(1)}%)</span>
            </div>
          ))}
        </div>
      </div>
    );
  }, []);

  // 生成雷达图数据
  const generateRadarData = (herbs: Herb[]) => {
    // 性味分类映射
    const natureMap: {[key: string]: number} = {
      '热': 5, '温': 4, '平': 3, '凉': 2, '寒': 1, '大寒': 0,
      '微温': 3.5, '微寒': 2.5
    };
    
    // 味道数值映射
    const tasteMap: {[key: string]: number} = {
      '辛': 5, '甘': 4, '酸': 3, '苦': 2, '咸': 1, '淡': 0.5
    };
    
    return herbs.map(herb => {
      // 基本药性得分
      const natureScore = herb.properties.性 ? (natureMap[herb.properties.性] || 3) : 3;
      
      // 味道综合得分 (计算平均值)
      const tasteScore = herb.properties.味 && herb.properties.味.length > 0
        ? herb.properties.味.reduce((sum, taste) => sum + (tasteMap[taste] || 3), 0) / herb.properties.味.length
        : 3;
        
      // 功效数量作为指标
      const functionScore = herb.functions ? Math.min(5, herb.functions.length) : 0;
      
      // 毒性指标
      const toxicityScore = herb.toxicity ? 5 : 1;
      
      // 通用使用率
      const usageScore = herb.commonUsage ? 5 : 2;
      
      return {
        name: herb.name,
        category: herb.category,
        data: {
          '性': natureScore,
          '味': tasteScore,
          '功效数量': functionScore,
          '毒性': toxicityScore,
          '常用度': usageScore
        }
      };
    });
  };
  
  // 渲染雷达图
  const renderRadarChart = (data: any[]) => {
    if (data.length === 0) return <div className="empty-chart">请选择药材进行分析</div>;
    
    // 获取所有维度
    const dimensions = Object.keys(data[0].data);
    const maxValue = 5; // 最大值统一为5
    
    // 计算每个维度的角度
    const angleStep = (Math.PI * 2) / dimensions.length;
    
    // 图表尺寸
    const size = 300;
    const radius = size / 2 - 30;
    const center = { x: size / 2, y: size / 2 };
    
    // 药材颜色
    const colors = [
      '#8D4D3B', '#2F6358', '#E4BB97', '#A37C40', '#566E3D',
      '#D96A29', '#A4B494', '#776B5D'
    ];
    
    return (
      <div className="radar-chart-container">
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          {/* 绘制雷达背景 */}
          {[1, 2, 3, 4, 5].map(level => {
            const pathPoints = dimensions.map((_, i) => {
              const angle = -Math.PI / 2 + i * angleStep;
              const levelRadius = (radius * level) / 5;
              return {
                x: center.x + levelRadius * Math.cos(angle),
                y: center.y + levelRadius * Math.sin(angle)
              };
            });
            
            const pathData = pathPoints.map((point, i) => 
              `${i === 0 ? 'M' : 'L'}${point.x},${point.y}`
            ).join(' ') + 'Z';
            
            return (
              <path 
                key={`level-${level}`}
                d={pathData}
                fill="none"
                stroke="#ccc"
                strokeWidth={1}
                opacity={0.5}
              />
            );
          })}
          
          {/* 绘制轴线 */}
          {dimensions.map((dimension, i) => {
            const angle = -Math.PI / 2 + i * angleStep;
            const point = {
              x: center.x + radius * Math.cos(angle),
              y: center.y + radius * Math.sin(angle)
            };
            
            return (
              <React.Fragment key={`axis-${dimension}`}>
                <line
                  x1={center.x}
                  y1={center.y}
                  x2={point.x}
                  y2={point.y}
                  stroke="#ccc"
                  strokeWidth={1}
                />
                <text
                  x={center.x + (radius + 15) * Math.cos(angle)}
                  y={center.y + (radius + 15) * Math.sin(angle)}
                  fontSize={12}
                  textAnchor="middle"
                  dominantBaseline="middle"
                >
                  {dimension}
                </text>
              </React.Fragment>
            );
          })}
          
          {/* 绘制数据多边形 */}
          {data.map((item, dataIndex) => {
            const pathPoints = dimensions.map((dimension, i) => {
              const angle = -Math.PI / 2 + i * angleStep;
              const value = item.data[dimension] || 0;
              const pointRadius = (radius * value) / maxValue;
              return {
                x: center.x + pointRadius * Math.cos(angle),
                y: center.y + pointRadius * Math.sin(angle)
              };
            });
            
            const pathData = pathPoints.map((point, i) => 
              `${i === 0 ? 'M' : 'L'}${point.x},${point.y}`
            ).join(' ') + 'Z';
            
            return (
              <path 
                key={`data-${dataIndex}`}
                d={pathData}
                fill={colors[dataIndex % colors.length]}
                fillOpacity={0.3}
                stroke={colors[dataIndex % colors.length]}
                strokeWidth={2}
              />
            );
          })}
        </svg>
        
        <div className="radar-legend">
          {data.map((item, index) => (
            <div key={index} className="legend-item">
              <span 
                className="legend-color" 
                style={{backgroundColor: colors[index % colors.length]}}
              ></span>
              <span className="legend-label">{item.name}</span>
              <span className="legend-category">({item.category})</span>
            </div>
          ))}
        </div>
      </div>
    );
  };
  
  // 渲染散点图
  const renderScatterPlot = (data: any[]) => {
    if (data.length === 0) return <div className="empty-chart">请选择药材进行分析</div>;
    
    // 选择前两个维度作为X和Y轴
    const dimensions = Object.keys(data[0].data);
    const xDimension = dimensions[0] || '性';
    const yDimension = dimensions[1] || '味';
    
    // 图表尺寸
    const size = 300;
    const padding = 40;
    const chartSize = size - padding * 2;
    
    // 药材颜色
    const colors = [
      '#8D4D3B', '#2F6358', '#E4BB97', '#A37C40', '#566E3D',
      '#D96A29', '#A4B494', '#776B5D'
    ];
    
    // 获取点的坐标
    const points = data.map(item => ({
      x: (item.data[xDimension] / 5) * chartSize + padding,
      y: size - ((item.data[yDimension] / 5) * chartSize + padding),
      name: item.name,
      category: item.category
    }));
    
    return (
      <div className="scatter-plot-container">
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          {/* X轴 */}
          <line
            x1={padding}
            y1={size - padding}
            x2={size - padding}
            y2={size - padding}
            stroke="#666"
            strokeWidth={1}
          />
          <text
            x={size / 2}
            y={size - 10}
            textAnchor="middle"
            fontSize={12}
          >
            {xDimension}
          </text>
          
          {/* Y轴 */}
          <line
            x1={padding}
            y1={padding}
            x2={padding}
            y2={size - padding}
            stroke="#666"
            strokeWidth={1}
          />
          <text
            x={15}
            y={size / 2}
            textAnchor="middle"
            fontSize={12}
            transform={`rotate(-90, 15, ${size / 2})`}
          >
            {yDimension}
          </text>
          
          {/* 绘制点 */}
          {points.map((point, index) => (
            <g key={`point-${index}`}>
              <circle
                cx={point.x}
                cy={point.y}
                r={6}
                fill={colors[index % colors.length]}
              />
              <text
                x={point.x}
                y={point.y - 10}
                textAnchor="middle"
                fontSize={10}
              >
                {point.name}
              </text>
            </g>
          ))}
        </svg>
        
        <div className="scatter-legend">
          <div className="axis-info">
            <span>X轴: {xDimension}</span>
            <span>Y轴: {yDimension}</span>
          </div>
          {data.map((item, index) => (
            <div key={index} className="legend-item">
              <span 
                className="legend-color" 
                style={{backgroundColor: colors[index % colors.length]}}
              ></span>
              <span className="legend-label">{item.name}</span>
              <span className="legend-category">({item.category})</span>
            </div>
          ))}
        </div>
      </div>
    );
  };

  // 渲染概览视图
  const renderOverviewView = () => (
    <div className="overview-view">
      <div className="dashboard-stats">
        <div className="stat-card">
          <h3>药材总数</h3>
          <div className="stat-value">{herbs.length}</div>
        </div>
        <div className="stat-card">
          <h3>分类总数</h3>
          <div className="stat-value">{categories.length}</div>
        </div>
        <div className="stat-card">
          <h3>常用药材</h3>
          <div className="stat-value">
            {herbs.filter(h => h.commonUsage === true).length}
          </div>
        </div>
        <div className="stat-card">
          <h3>毒性药材</h3>
          <div className="stat-value">
            {herbs.filter(h => h.toxicity === true).length}
          </div>
        </div>
      </div>

      <div className="dashboard-quicklinks">
        <h3>快速访问</h3>
        <div className="quicklinks-grid">
          <div className="quicklink-card" onClick={() => handleViewChange('classification')}>
            <div className="quicklink-icon">🌿</div>
            <h4>分类与体系</h4>
            <p>浏览本草纲目药材分类体系</p>
          </div>
          <div className="quicklink-card" onClick={() => handleViewChange('properties')}>
            <div className="quicklink-icon">🧪</div>
            <h4>属性分析</h4>
            <p>分析药材的性味归经特性</p>
          </div>
          <div className="quicklink-card" onClick={() => handleViewChange('relations')}>
            <div className="quicklink-icon">🔄</div>
            <h4>关联网络</h4>
            <p>探索药材间的配伍关系</p>
          </div>
          <div className="quicklink-card" onClick={() => handleViewChange('geographic')}>
            <div className="quicklink-icon">🗺️</div>
            <h4>地理分布</h4>
            <p>查看药材的产地和分布</p>
          </div>
          <div className="quicklink-card" onClick={() => handleViewChange('textual')}>
            <div className="quicklink-icon">📚</div>
            <h4>文本分析</h4>
            <p>挖掘本草纲目中的文本信息</p>
          </div>
        </div>
      </div>

      <div className="recent-herbs">
        <h3>常用药材</h3>
        <div className="herbs-grid">
          {herbs.filter(h => h.commonUsage === true).slice(0, 12).map((herb, index) => (
            <div key={index} className="herb-card" onClick={() => handleHerbSelect(herb)}>
              <div className="herb-image">
                <img src="/assets/images/herb_placeholders/default.jpg" alt={herb.name} />
              </div>
              <h4>{herb.name}</h4>
              <p>{herb.category}</p>
            </div>
          ))}
        </div>
      </div>
    </div>
  );

  // 渲染分类体系视图
  const renderClassificationView = () => {
    // 根据选择的维度获取相应的数据
    let hierarchyData: {[key: string]: Herb[]} = {};
    let statsData: {[key: string]: number} = {};
    
    switch (classificationDimension) {
      case '分类':
        herbs.forEach(herb => {
          if (!hierarchyData[herb.category]) {
            hierarchyData[herb.category] = [];
          }
          hierarchyData[herb.category].push(herb);
        });
        statsData = categoryStats;
        break;
      case '性味归经':
        herbs.forEach(herb => {
          if (herb.properties && herb.properties.性) {
            const key = herb.properties.性;
            if (!hierarchyData[key]) {
              hierarchyData[key] = [];
            }
            hierarchyData[key].push(herb);
          }
        });
        statsData = natureStats;
        break;
      case '功能主治':
        const functionMap: {[key: string]: Herb[]} = {};
        herbs.forEach(herb => {
          if (herb.functions) {
            herb.functions.forEach(func => {
              if (!functionMap[func]) {
                functionMap[func] = [];
              }
              if (!functionMap[func].includes(herb)) {
                functionMap[func].push(herb);
              }
            });
          }
        });
        hierarchyData = functionMap;
        statsData = functionStats;
        break;
      case '毒性副作用':
        hierarchyData = {
          '有毒': herbs.filter(h => h.toxicity),
          '无毒': herbs.filter(h => !h.toxicity)
        };
        statsData = {
          '有毒': herbs.filter(h => h.toxicity).length,
          '无毒': herbs.filter(h => !h.toxicity).length
        };
        break;
    }
    
    // 获取排序后的类别列表
    const sortedCategories = Object.keys(hierarchyData).sort((a, b) => 
      (statsData[b] || 0) - (statsData[a] || 0)
    );

    // 修改饼图颜色生成逻辑，使用更多样的颜色
    const pieColors = sortedCategories.map((_, i) => 
      `hsl(${(i * 360 / sortedCategories.length) % 360}, 70%, 55%)`
    );
    
    return (
      <div className="classification-view">
        <div className="dimension-tabs">
          {(['分类', '性味归经', '功能主治', '毒性副作用'] as ClassificationDimension[]).map(dimension => (
            <button 
              key={dimension}
              className={`dimension-tab ${classificationDimension === dimension ? 'active' : ''}`}
              onClick={() => handleDimensionChange(dimension)}
            >
              {dimension}
            </button>
          ))}
        </div>
        
        <div className="classification-content">
          <div className="classification-tree">
            <h3>{classificationDimension}体系</h3>
            <div className="tree-container">
              {sortedCategories.map(category => (
                <div key={category} className="tree-category">
                  <div 
                    className="category-header" 
                    onClick={() => toggleCategoryExpand(category)}
                  >
                    <span className="category-name">{category}</span>
                    <span className="category-count">{hierarchyData[category].length}</span>
                    <span 
                      className={`expand-icon ${expandedCategories[category] ? 'expanded' : ''}`}
                    >
                      ▼
                    </span>
                  </div>
                  <div 
                    className={`category-items ${expandedCategories[category] ? 'expanded' : ''}`}
                  >
                    {hierarchyData[category].map((herb, idx) => (
                      <div 
                        key={idx} 
                        className={`herb-item ${selectedHerb === herb ? 'selected' : ''}`}
                        onClick={(e) => {
                          e.stopPropagation(); // 防止冒泡触发分类展开/折叠
                          handleHerbSelect(herb);
                        }}
                      >
                        {herb.name}
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          </div>
          
          <div className="classification-stats">
            <h3>统计分析</h3>
            <div className="chart-container">
              <div className="bar-chart" ref={categoryChartRef}>
                <div className="chart-placeholder">
                  {sortedCategories.slice(0, 10).map((category, index) => (
                    <div key={index} className="stat-bar-container">
                      <div className="stat-bar-label">{category}</div>
                      <div className="stat-bar-wrapper">
                        <div 
                          className="stat-bar" 
                          style={{
                            width: `${(statsData[category] / Math.max(...Object.values(statsData))) * 100}%`,
                            backgroundColor: `hsl(${index * 36}, 70%, 60%)`
                          }}
                        ></div>
                        <span className="stat-bar-value">{statsData[category]}</span>
                      </div>
                    </div>
                  ))}
                </div>
              </div>
              
              <div className="pie-chart" ref={pieChartRef}>
                {renderPieChart(statsData, pieColors)}
              </div>
            </div>
          </div>
          
          <div className="herb-detail-panel">
            {selectedHerb ? (
              <div className="herb-detail">
                <h3>{selectedHerb.name}</h3>
                <div className="herb-image-large">
                  <img src="/assets/images/herb_placeholders/default.jpg" alt={selectedHerb.name} />
                </div>
                <div className="herb-info">
                  <p><strong>分类：</strong> {selectedHerb.category}</p>
                  <p><strong>性味：</strong> {selectedHerb.properties.性}、{selectedHerb.properties.味.join('、')}</p>
                  <p><strong>功效：</strong> {selectedHerb.functions.join('，')}</p>
                  <p><strong>毒性：</strong> {selectedHerb.toxicity ? '有毒' : '无毒'}</p>
                  {selectedHerb.description && (
                    <p><strong>描述：</strong> {selectedHerb.description}</p>
                  )}
                </div>
                <button className="view-more-btn">查看详情</button>
              </div>
            ) : (
              <div className="no-herb-selected">
                <p>点击左侧药材查看详情</p>
              </div>
            )}
          </div>
        </div>
      </div>
    );
  };

  // 渲染属性与特性分析视图
  const renderPropertiesView = () => {
    const radarData = generateRadarData(selectedHerbs);
    
    return (
      <div className="properties-view">
        <div className="properties-content">
          <div className="properties-sidebar">
            <div className="herb-selector">
              <h3>药材选择</h3>
              <div className="herb-search">
                <input
                  type="text"
                  placeholder="搜索药材..."
                  value={filterOptions.keyword}
                  onChange={handleKeywordChange}
                />
              </div>
              <div className="herb-list">
                {herbs
                  .filter(herb => 
                    herb.name.includes(filterOptions.keyword) ||
                    herb.category.includes(filterOptions.keyword)
                  )
                  .slice(0, 20)
                  .map(herb => (
                    <div
                      key={herb.id}
                      className={`herb-list-item ${selectedHerbs.some(h => h.id === herb.id) ? 'selected' : ''}`}
                      onClick={() => handleHerbMultiSelect(herb)}
                    >
                      <span className="herb-name">{herb.name}</span>
                      <span className="herb-category">{herb.category}</span>
                    </div>
                  ))}
              </div>
              <div className="selected-herbs">
                <h4>已选择 ({selectedHerbs.length}/5)</h4>
                <div className="selected-tags">
                  {selectedHerbs.map(herb => (
                    <span key={herb.id} className="selected-tag">
                      {herb.name}
                      <button onClick={() => handleHerbMultiSelect(herb)}>&times;</button>
                    </span>
                  ))}
                </div>
              </div>
            </div>
            
            <div className="dimension-selector">
              <h3>属性维度</h3>
              <div className="dimension-options">
                {(['性', '味', '功效', '毒性'] as PropertyDimension[]).map(dimension => (
                  <label key={dimension} className="dimension-option">
                    <input
                      type="checkbox"
                      checked={propertyDimensions.includes(dimension)}
                      onChange={() => handleDimensionToggle(dimension)}
                    />
                    <span>{dimension}</span>
                  </label>
                ))}
              </div>
            </div>
            
            <div className="view-mode-selector">
              <h3>图表类型</h3>
              <div className="mode-options">
                <label className="mode-option">
                  <input
                    type="radio"
                    checked={comparisonMode === 'radar'}
                    onChange={() => setComparisonMode('radar')}
                  />
                  <span>雷达图</span>
                </label>
                <label className="mode-option">
                  <input
                    type="radio"
                    checked={comparisonMode === 'scatter'}
                    onChange={() => setComparisonMode('scatter')}
                  />
                  <span>散点图</span>
                </label>
              </div>
            </div>
          </div>
          
          <div className="properties-main">
            <div className="chart-header">
              <h2>药材属性对比</h2>
              <p className="chart-description">
                {comparisonMode === 'radar'
                  ? '雷达图展示了所选药材在不同属性维度上的对比情况'
                  : '散点图展示了所选药材在两个不同属性维度上的相对位置'}
              </p>
            </div>
            
            <div className="chart-container">
              {comparisonMode === 'radar'
                ? renderRadarChart(radarData)
                : renderScatterPlot(radarData)
              }
            </div>
            
            <div className="property-analysis">
              <h3>属性分析结果</h3>
              {selectedHerbs.length > 0 ? (
                <div className="analysis-content">
                  <p>所选药材整体特性分析：</p>
                  <ul className="analysis-list">
                    {selectedHerbs.length > 1 && (
                      <li>已选择{selectedHerbs.length}种不同药材进行对比分析</li>
                    )}
                    {selectedHerbs.filter(h => h.properties.性 === '温' || h.properties.性 === '热').length > 
                     selectedHerbs.filter(h => h.properties.性 === '寒' || h.properties.性 === '凉').length ? (
                      <li>所选药材整体偏温热性</li>
                    ) : (
                      <li>所选药材整体偏寒凉性</li>
                    )}
                    {selectedHerbs.filter(h => h.toxicity).length > 0 && (
                      <li>所选药材中有{selectedHerbs.filter(h => h.toxicity).length}种具有毒性，使用时需谨慎</li>
                    )}
                    {selectedHerbs.filter(h => h.commonUsage).length === selectedHerbs.length && (
                      <li>所选药材均为常用药材，临床应用广泛</li>
                    )}
                  </ul>
                </div>
              ) : (
                <p className="empty-analysis">请选择药材进行分析</p>
              )}
            </div>
          </div>
        </div>
      </div>
    );
  };

  // 渲染关联与网络视图
  const renderRelationsView = () => {
    return (
      <div className="relations-view">
        <div className="relations-controls">
          <div className="control-panel">
            <h3>网络控制面板</h3>
            
            <div className="control-group">
              <label>关系强度阈值：{strengthThreshold.toFixed(1)}</label>
              <input 
                type="range" 
                min="0" 
                max="1" 
                step="0.1" 
                value={strengthThreshold}
                onChange={handleStrengthThresholdChange}
                className="slider"
              />
            </div>
            
            <div className="control-group">
              <label>中心药材选择：</label>
              <select 
                value={centerHerb} 
                onChange={(e) => handleCenterHerbChange(e.target.value)}
              >
                <option value="">全部药材</option>
                {herbs.slice(0, 20).map(herb => (
                  <option key={herb.id} value={herb.id}>{herb.name}</option>
                ))}
              </select>
            </div>
            
            <div className="control-group">
              <label>聚类算法：</label>
              <div className="button-group">
                <button 
                  className={clusterAlgorithm === 'louvain' ? 'active' : ''}
                  onClick={() => handleClusterAlgorithmChange('louvain')}
                >
                  社区检测
                </button>
                <button 
                  className={clusterAlgorithm === 'category' ? 'active' : ''}
                  onClick={() => handleClusterAlgorithmChange('category')}
                >
                  分类聚类
                </button>
                <button 
                  className={clusterAlgorithm === 'degree' ? 'active' : ''}
                  onClick={() => handleClusterAlgorithmChange('degree')}
                >
                  连接度聚类
                </button>
              </div>
            </div>
            
            <div className="control-group">
              <label>显示选项：</label>
              <div className="checkbox-group">
                <label>
                  <input 
                    type="checkbox" 
                    checked={showLabels} 
                    onChange={toggleLabels}
                  />
                  显示药材名称
                </label>
              </div>
            </div>
          </div>
          
          <div className="network-stats">
            <h3>网络统计数据</h3>
            <div className="stats-grid">
              <div className="stat-item">
                <span className="stat-label">节点数量：</span>
                <span className="stat-value">{networkNodes.length}</span>
              </div>
              <div className="stat-item">
                <span className="stat-label">连接数量：</span>
                <span className="stat-value">{networkLinks.length}</span>
              </div>
              <div className="stat-item">
                <span className="stat-label">聚类数量：</span>
                <span className="stat-value">
                  {networkNodes.length > 0
                    ? new Set(networkNodes.map(n => n.group)).size
                    : 0}
                </span>
              </div>
              <div className="stat-item">
                <span className="stat-label">平均连接度：</span>
                <span className="stat-value">
                  {networkNodes.length > 0
                    ? (networkLinks.length * 2 / networkNodes.length).toFixed(2)
                    : '0.00'}
                </span>
              </div>
            </div>
            
            {selectedNode && networkNodes.find(n => n.id === selectedNode) && (
              <div className="selected-node-info">
                <h4>选中节点信息</h4>
                {(() => {
                  const node = networkNodes.find(n => n.id === selectedNode);
                  const herb = herbs.find(h => h.id === selectedNode);
                  
                  if (!node || !herb) return null;
                  
                  // 计算与该节点相关的连接
                  const relatedLinks = networkLinks.filter(
                    link => link.source === selectedNode || link.target === selectedNode
                  );
                  
                  return (
                    <div className="node-details">
                      <p><strong>{herb.name}</strong> ({herb.category})</p>
                      <p>连接数：{relatedLinks.length}</p>
                      <p>聚类组：{node.group}</p>
                      <div className="related-herbs">
                        <p>相关药材：</p>
                        <div className="related-list">
                          {relatedLinks.map((link, idx) => {
                            const relatedId = link.source === selectedNode ? link.target : link.source;
                            const relatedHerb = herbs.find(h => h.id === relatedId);
                            if (!relatedHerb) return null;
                            
                            return (
                              <div key={idx} className="related-item">
                                <span className="relation-type" style={{
                                  backgroundColor: getRelationColor(link.type)
                                }}></span>
                                <span className="relation-name">{relatedHerb.name}</span>
                                <span className="relation-info">
                                  {link.type} ({(link.strength * 100).toFixed(0)}%)
                                </span>
                              </div>
                            );
                          })}
                        </div>
                      </div>
                    </div>
                  );
                })()}
              </div>
            )}
          </div>
        </div>
        
        <div className="network-container" ref={networkRef}>
          {networkNodes.length > 0 ? (
            <svg width="100%" height="600">
              {/* 绘制连接线 */}
              {networkLinks.map((link, index) => {
                // 找到源和目标节点
                const source = networkNodes.find(n => n.id === link.source);
                const target = networkNodes.find(n => n.id === link.target);
                
                if (!source || !target) return null;
                
                // 基于关系类型设置线条颜色
                const linkColor = getRelationColor(link.type);
                
                // 强调选中节点的连接
                const isHighlighted = selectedNode && 
                  (source.id === selectedNode || target.id === selectedNode);
                
                // 确保坐标存在
                const sourceX = source.x || 0;
                const sourceY = source.y || 0;
                const targetX = target.x || 0;
                const targetY = target.y || 0;
                
                return (
                  <line
                    key={`link-${index}`}
                    x1={sourceX}
                    y1={sourceY}
                    x2={targetX}
                    y2={targetY}
                    stroke={linkColor}
                    strokeWidth={link.strength * 3}
                    opacity={isHighlighted ? 0.9 : 0.6}
                    className="network-link"
                    strokeDasharray={isHighlighted ? "none" : "none"}
                  />
                );
              })}
              
              {/* 绘制节点 */}
              {networkNodes.map((node, index) => {
                // 基于组设置节点颜色
                const groupColors = ['#8D4D3B', '#2F6358', '#E4BB97', '#A37C40', '#566E3D', '#D96A29'];
                const color = groupColors[(node.group || 1) % groupColors.length];
                
                // 节点大小基于值或默认值
                const nodeSize = node.value ? 5 + node.value * 2 : 10;
                
                // 高亮选中的节点
                const isSelected = selectedNode === node.id;
                
                // 高亮与选中节点相关的节点
                const isRelated = selectedNode && networkLinks.some(
                  link => (link.source === selectedNode && link.target === node.id) ||
                         (link.target === selectedNode && link.source === node.id)
                );
                
                // 确保坐标存在
                const x = node.x || 0;
                const y = node.y || 0;
                
                return (
                  <g key={`node-${index}`}>
                    <circle
                      className="network-node"
                      cx={x}
                      cy={y}
                      r={isSelected ? nodeSize * 1.3 : nodeSize}
                      fill={color}
                      stroke={isSelected ? "#000" : isRelated ? "#555" : "#fff"}
                      strokeWidth={isSelected ? 2 : isRelated ? 1.5 : 1}
                      onClick={() => handleNodeSelect(node.id)}
                    />
                    {(showLabels || isSelected || isRelated) && (
                      <text
                        className="node-label"
                        x={x}
                        y={y - nodeSize - 5}
                        textAnchor="middle"
                        fontSize={isSelected ? 12 : 10}
                        fontWeight={isSelected ? "bold" : "normal"}
                      >
                        {node.name}
                      </text>
                    )}
                  </g>
                );
              })}
            </svg>
          ) : (
            <div className="empty-network">
              <p>无法显示网络图。请调整筛选条件或加载更多数据。</p>
            </div>
          )}
        </div>
        
        <div className="network-detail">
          <div className="cluster-analysis">
            <h3>聚类分析结果</h3>
            {networkNodes.length > 0 ? (
              <div className="cluster-content">
                <p>基于{
                  clusterAlgorithm === 'louvain' ? '社区检测算法' : 
                  clusterAlgorithm === 'category' ? '药材分类' : '连接度'
                }的聚类结果：</p>
                
                <div className="cluster-groups">
                  {Array.from(new Set(networkNodes.map(n => n.group))).sort().map(group => {
                    const groupNodes = networkNodes.filter(n => n.group === group);
                    if (groupNodes.length === 0) return null;
                    
                    // 基于组设置颜色
                    const groupColors = ['#8D4D3B', '#2F6358', '#E4BB97', '#A37C40', '#566E3D', '#D96A29'];
                    const color = groupColors[(group || 1) % groupColors.length];
                    
                    return (
                      <div key={`group-${group}`} className="cluster-group">
                        <div className="group-header">
                          <span 
                            className="group-color" 
                            style={{backgroundColor: color}}
                          ></span>
                          <span className="group-name">聚类 {group}</span>
                          <span className="group-count">{groupNodes.length}个药材</span>
                        </div>
                        <div className="group-members">
                          {groupNodes.slice(0, 8).map(node => (
                            <span 
                              key={node.id} 
                              className={`member-tag ${selectedNode === node.id ? 'selected' : ''}`}
                              onClick={() => handleNodeSelect(node.id)}
                            >
                              {node.name}
                            </span>
                          ))}
                          {groupNodes.length > 8 && <span className="more-tag">+{groupNodes.length - 8}个</span>}
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            ) : (
              <p className="empty-analysis">无聚类数据可用。请调整筛选条件。</p>
            )}
          </div>
          
          <div className="relation-types">
            <h3>关系类型说明</h3>
            <div className="type-list">
              <div className="type-item">
                <span className="type-color" style={{backgroundColor: '#2F6358'}}></span>
                <span className="type-name">配伍</span>
                <span className="type-desc">两种药材配合使用，效果良好</span>
              </div>
              <div className="type-item">
                <span className="type-color" style={{backgroundColor: '#8D4D3B'}}></span>
                <span className="type-name">相须</span>
                <span className="type-desc">药材相互促进，增强疗效</span>
              </div>
              <div className="type-item">
                <span className="type-color" style={{backgroundColor: '#A37C40'}}></span>
                <span className="type-name">相使</span>
                <span className="type-desc">一种药材辅助另一种药材发挥作用</span>
              </div>
              <div className="type-item">
                <span className="type-color" style={{backgroundColor: '#D96A29'}}></span>
                <span className="type-name">相畏</span>
                <span className="type-desc">一种药材可制约另一种药材的毒性</span>
              </div>
              <div className="type-item">
                <span className="type-color" style={{backgroundColor: '#E41E25'}}></span>
                <span className="type-name">相杀</span>
                <span className="type-desc">一种药材可消除另一种药材的毒性</span>
              </div>
              <div className="type-item">
                <span className="type-color" style={{backgroundColor: '#7E2E8D'}}></span>
                <span className="type-name">相恶</span>
                <span className="type-desc">两种药材配合，功效减弱</span>
              </div>
              <div className="type-item">
                <span className="type-color" style={{backgroundColor: '#000000'}}></span>
                <span className="type-name">相反</span>
                <span className="type-desc">两种药材配合，会产生不良反应</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  };

  // 根据历史时期获取药材位置
  const getHerbLocationsByPeriod = (period: HistoricalPeriod) => {
    const periodLocations: {[key: string]: [number, number]} = {};
    
    herbs.forEach(herb => {
      if (herb.historicalOrigins && herb.historicalOrigins[period]) {
        periodLocations[herb.id] = herb.historicalOrigins[period] as [number, number];
      } else if (herb.origin) {
        // 如果没有特定时期的数据，则使用默认位置
        periodLocations[herb.id] = herb.origin;
      }
    });
    
    return periodLocations;
  };

  // 获取版本变更信息
  const getVersionChanges = (version: string) => {
    const changes: {herb: Herb, oldText: string, newText: string}[] = [];
    
    herbs.forEach(herb => {
      if (herb.versionChanges && herb.versionChanges[version]) {
        const newText = herb.versionChanges[version];
        const versions = Object.keys(herb.versionChanges);
        const versionIndex = versions.indexOf(version);
        let oldText = "无记载";
        
        if (versionIndex > 0) {
          oldText = herb.versionChanges[versions[versionIndex - 1]] || "无记载";
        }
        
        changes.push({
          herb,
          oldText,
          newText
        });
      }
    });
    
    return changes;
  };

  // 渲染地理与历史数据视图
  const renderGeographicView = () => {
    // 中国省份简化坐标数据 - 仅作演示用
    const provinceCoordinates: {[key: string]: [number, number]} = {
      '北京': [116.4, 39.9],
      '上海': [121.4, 31.2],
      '广州': [113.2, 23.1],
      '成都': [104.0, 30.6],
      '西安': [108.9, 34.2],
      '哈尔滨': [126.6, 45.7],
      '乌鲁木齐': [87.6, 43.8],
      '拉萨': [91.1, 29.6],
      '南京': [118.8, 32.0],
      '武汉': [114.3, 30.5]
    };

    // 历史时期选项
    const periods: HistoricalPeriod[] = ['先秦', '汉代', '魏晋南北朝', '隋唐', '宋元', '明代', '清代', '现代'];
    
    // 版本比较选项
    const versions = ['初刻本(1593年)', '重刻本(1603年)', '绘图本(1640年)', '知新本(1765年)', '现代整理本'];
    
    // 根据当前历史时期获取药材位置
    const periodLocations = getHerbLocationsByPeriod(historicalPeriod);
    
    // 获取版本变更信息
    const versionDifferences = getVersionChanges(compareVersion);
    
    return (
      <div className="geographic-view">
        <div className="map-controls">
          <div className="view-mode-buttons">
            <h3>视图模式</h3>
            <div className="button-group">
              <button 
                className={mapViewMode === 'origin' ? 'active' : ''}
                onClick={() => handleMapViewModeChange('origin')}
              >
                原产地视图
              </button>
              <button 
                className={mapViewMode === 'distribution' ? 'active' : ''}
                onClick={() => handleMapViewModeChange('distribution')}
              >
                分布区域
              </button>
              <button 
                className={mapViewMode === 'heatmap' ? 'active' : ''}
                onClick={() => handleMapViewModeChange('heatmap')}
              >
                使用热力
              </button>
              <button 
                className={mapViewMode === 'comparison' ? 'active' : ''}
                onClick={() => handleMapViewModeChange('comparison')}
              >
                版本对比
              </button>
            </div>
          </div>
          
          <div className="timeline-control">
            <h3>历史时期: {historicalPeriod}</h3>
            <div className="timeline-slider">
              <div className="timeline-track">
                {periods.map((period, index) => (
                  <div 
                    key={period}
                    className={`timeline-point ${historicalPeriod === period ? 'active' : ''}`}
                    style={{ left: `${index * (100 / (periods.length - 1))}%` }}
                    onClick={() => handleHistoricalPeriodChange(period)}
                    title={period}
                  >
                    <div className="timeline-marker"></div>
                    <div className="timeline-label">{period}</div>
                  </div>
                ))}
              </div>
            </div>
          </div>
          
          {mapViewMode === 'comparison' && (
            <div className="version-selector">
              <h3>版本选择</h3>
              <select 
                value={compareVersion}
                onChange={handleCompareVersionChange}
              >
                {versions.map(version => (
                  <option key={version} value={version}>{version}</option>
                ))}
              </select>
              <p className="version-info">
                比较《本草纲目》不同版本间的药材记载差异
              </p>
            </div>
          )}
          
          <div className="map-tools">
            <div className="zoom-controls">
              <button onClick={() => handleMapZoom(true)}>+</button>
              <button onClick={() => handleMapZoom(false)}>-</button>
            </div>
            
            <div className="map-legend">
              <h4>图例</h4>
              {mapViewMode === 'origin' && (
                <div className="legend-item">
                  <span className="legend-marker" style={{backgroundColor: 'var(--primary-color)'}}></span>
                  <span className="legend-text">药材原产地</span>
                </div>
              )}
              {mapViewMode === 'distribution' && (
                <>
                  <div className="legend-item">
                    <span className="legend-marker" style={{backgroundColor: 'var(--primary-color)'}}></span>
                    <span className="legend-text">主要产区</span>
                  </div>
                  <div className="legend-item">
                    <span className="legend-marker" style={{backgroundColor: 'var(--secondary-color)'}}></span>
                    <span className="legend-text">次要产区</span>
                  </div>
                </>
              )}
              {mapViewMode === 'heatmap' && (
                <>
                  <div className="legend-item">
                    <div className="legend-gradient"></div>
                    <div className="legend-labels">
                      <span>低</span>
                      <span>高</span>
                    </div>
                  </div>
                </>
              )}
            </div>
          </div>
        </div>
        
        <div className="map-content">
          <div className="map-container" ref={mapRef}>
            <div className="china-map" style={{transform: `scale(${mapZoom / 5})`}}>
              {/* 简化版中国地图轮廓SVG */}
              <svg width="100%" height="100%" viewBox="0 0 1000 800" preserveAspectRatio="xMidYMid meet">
                <path 
                  d="M250,120 Q400,50 600,100 Q800,150 850,300 Q900,500 750,650 Q600,750 400,700 Q200,650 150,500 Q100,300 250,120 Z" 
                  fill="#f0f0f0" 
                  stroke="#ccc" 
                  strokeWidth="2"
                />
                
                {/* 渲染省份标记点 */}
                {Object.entries(provinceCoordinates).map(([province, [lng, lat]]) => {
                  // 将经纬度映射到SVG坐标
                  const x = (lng - 70) * 20;
                  const y = 800 - (lat - 15) * 25;
                  
                  return (
                    <g key={province}>
                      <circle 
                        cx={x} 
                        cy={y} 
                        r={6} 
                        fill="var(--secondary-color)" 
                        opacity={0.7}
                      />
                      <text 
                        x={x} 
                        y={y - 10} 
                        textAnchor="middle" 
                        fontSize={10}
                      >
                        {province}
                      </text>
                    </g>
                  );
                })}
                
                {/* 渲染药材位置标记 - 更新为使用当前历史时期的位置 */}
                {mapViewMode === 'origin' && Object.entries(periodLocations).slice(0, 20).map(([herbId, [lng, lat]]) => {
                  const herb = herbs.find(h => h.id === herbId);
                  if (!herb) return null;
                  
                  // 将经纬度映射到SVG坐标
                  const x = (lng - 70) * 20;
                  const y = 800 - (lat - 15) * 25;
                  
                  return (
                    <g key={herbId}>
                      <circle 
                        cx={x} 
                        cy={y} 
                        r={8} 
                        fill="var(--primary-color)" 
                        opacity={0.8}
                      />
                      <text 
                        x={x} 
                        y={y - 12} 
                        textAnchor="middle" 
                        fontSize={12}
                        fill="#333"
                      >
                        {herb.name}
                      </text>
                    </g>
                  );
                })}
                
                {/* 热力图视图 */}
                {mapViewMode === 'heatmap' && (
                  <>
                    <circle cx="300" cy="200" r="80" fill="rgba(255, 0, 0, 0.2)" />
                    <circle cx="400" cy="300" r="100" fill="rgba(255, 0, 0, 0.3)" />
                    <circle cx="600" cy="250" r="120" fill="rgba(255, 0, 0, 0.2)" />
                    <circle cx="650" cy="400" r="70" fill="rgba(255, 0, 0, 0.4)" />
                    <circle cx="500" cy="500" r="90" fill="rgba(255, 0, 0, 0.3)" />
                  </>
                )}
              </svg>
            </div>
          </div>
          
          <div className="map-sidebar">
            {mapViewMode === 'origin' && (
              <div className="herb-origin-list">
                <h3>药材原产地列表 ({historicalPeriod})</h3>
                <div className="origin-herbs">
                  {Object.entries(periodLocations).slice(0, 12).map(([herbId, [lng, lat]]) => {
                    const herb = herbs.find(h => h.id === herbId);
                    if (!herb) return null;
                    
                    return (
                      <div key={herbId} className="origin-herb-item">
                        <span className="herb-name">{herb.name}</span>
                        <span className="herb-origin">{lat.toFixed(2)}°N, {lng.toFixed(2)}°E</span>
                      </div>
                    );
                  })}
                </div>
              </div>
            )}
            
            {mapViewMode === 'heatmap' && (
              <div className="region-stats">
                <h3>区域统计 ({historicalPeriod})</h3>
                <div className="region-bars">
                  {Object.entries(regionHeatmap).map(([region, value]) => (
                    <div 
                      key={region} 
                      className={`region-bar-item ${selectedRegion === region ? 'selected' : ''}`}
                      onClick={() => handleRegionSelect(region)}
                    >
                      <span className="region-name">{region}</span>
                      <div className="region-bar-wrapper">
                        <div 
                          className="region-bar" 
                          style={{ width: `${value}%`, backgroundColor: `hsl(0, 80%, ${50 + value/5}%)` }}
                        ></div>
                      </div>
                      <span className="region-value">{value}</span>
                    </div>
                  ))}
                </div>
                
                {selectedRegion && (
                  <div className="region-herbs">
                    <h4>{selectedRegion}常见药材</h4>
                    <div className="region-herb-tags">
                      {regionHerbs.map(herb => (
                        <span key={herb.id} className="region-herb-tag">{herb.name}</span>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            )}
            
            {mapViewMode === 'comparison' && (
              <div className="version-diff">
                <h3>版本差异对比</h3>
                <p className="compare-info">对比《本草纲目》{compareVersion}与原版的差异</p>
                
                <div className="diff-stats">
                  <div className="diff-stat-item">
                    <span className="diff-label">新增药材</span>
                    <span className="diff-value">{Math.floor(Math.random() * 10) + 5}种</span>
                  </div>
                  <div className="diff-stat-item">
                    <span className="diff-label">修订记载</span>
                    <span className="diff-value">{Math.floor(Math.random() * 30) + 20}条</span>
                  </div>
                  <div className="diff-stat-item">
                    <span className="diff-label">产地变更</span>
                    <span className="diff-value">{Math.floor(Math.random() * 15) + 5}处</span>
                  </div>
                </div>
                
                <div className="diff-examples">
                  <h4>主要修订示例</h4>
                  {versionDifferences.length > 0 ? (
                    versionDifferences.slice(0, 3).map((diff, index) => (
                      <div key={index} className="diff-example-item">
                        <div className="diff-herb">{diff.herb.name}</div>
                        <div className="diff-content">
                          <p><span className="old-version">原版: </span>{diff.oldText}</p>
                          <p><span className="new-version">新版: </span>{diff.newText}</p>
                        </div>
                      </div>
                    ))
                  ) : (
                    <div className="diff-example-item">
                      <div className="diff-herb">人参</div>
                      <div className="diff-content">
                        <p><span className="old-version">原版: </span>生于辽东山谷。</p>
                        <p><span className="new-version">新版: </span>生于辽东山谷，以及高丽北部地区。</p>
                      </div>
                    </div>
                  )}
                </div>
              </div>
            )}
          </div>
        </div>
      </div>
    );
  };

  // 渲染占位视图
  const renderPlaceholderView = (title: string) => (
    <div className="placeholder-view">
      <h3>{title}视图</h3>
      <p>此视图正在开发中...</p>
    </div>
  );

  // 处理地图视图模式变化
  const handleMapViewModeChange = (mode: MapViewMode) => {
    setMapViewMode(mode);
  };

  // 处理历史时期变化
  const handleHistoricalPeriodChange = (period: HistoricalPeriod) => {
    setHistoricalPeriod(period);
  };

  // 处理版本比较选择变化
  const handleCompareVersionChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    setCompareVersion(e.target.value);
  };

  // 处理地区选择
  const handleRegionSelect = (region: string) => {
    setSelectedRegion(region);
    
    // 模拟根据选定区域筛选药材
    const regionFilteredHerbs = herbs.filter((_, index) => index % 5 === 0);
    setRegionHerbs(regionFilteredHerbs.slice(0, 8));
  };

  // 处理地图缩放
  const handleMapZoom = (zoomIn: boolean) => {
    setMapZoom(prev => {
      const newZoom = zoomIn ? prev + 1 : prev - 1;
      return Math.max(3, Math.min(newZoom, 8)); // 限制缩放范围
    });
  };

  // 获取关系类型的颜色
  const getRelationColor = (type: string) => {
    switch(type) {
      case '配伍': return '#2F6358';
      case '相须': return '#8D4D3B';
      case '相使': return '#A37C40';
      case '相畏': return '#D96A29';
      case '相杀': return '#E41E25';
      case '相恶': return '#7E2E8D';
      case '相反': return '#000000';
      default: return '#999';
    }
  };

  // 文本分析功能
  
  // 生成词云数据
  const generateWordCloudData = (herbsList: Herb[]) => {
    // 提取所有药材描述
    const allDescriptions = herbsList.map(herb => herb.description || '').join(' ');
    
    // 分词处理（简化版）
    const commonWords = ['的', '地', '得', '和', '与', '及', '或', '并', '等', '在', '中', '为', '有', '是', '以'];
    const words = allDescriptions.split(/[,，.。;；\s]+/);
    
    // 统计词频
    const wordCount: {[key: string]: number} = {};
    words.forEach(word => {
      if (word.length >= 2 && !commonWords.includes(word)) { // 排除单字和常见虚词
        wordCount[word] = (wordCount[word] || 0) + 1;
      }
    });
    
    // 转换格式并排序
    const cloudData = Object.entries(wordCount)
      .map(([text, value]) => ({ text, value }))
      .filter(item => item.value > 1) // 过滤掉只出现一次的词
      .sort((a, b) => b.value - a.value)
      .slice(0, 100); // 限制数量
    
    setWordCloudData(cloudData);
  };
  
  // 搜索历代评价
  const searchHistoricalQuotes = (herbName: string) => {
    setSelectedHerbForText(herbName);
    
    // 模拟数据 - 实际应用中应该从数据库或API获取
    const mockQuotes = [
      { period: '汉代 · 神农本草经', quote: `${herbName}，味甘，平，无毒。主治五脏百病，补益精气，增智延年。`, source: '《神农本草经》' },
      { period: '南北朝 · 本草经集注', quote: `${herbName}，${Math.random() > 0.5 ? '气温' : '气平'}，味${Math.random() > 0.5 ? '甘' : '苦'}。主治${Math.random() > 0.5 ? '热病' : '寒病'}，${Math.random() > 0.5 ? '解毒' : '益气'}。`, source: '《本草经集注》' },
      { period: '唐代 · 新修本草', quote: `${herbName}，性${Math.random() > 0.5 ? '温' : '寒'}，味${Math.random() > 0.5 ? '甘' : '苦'}。能${Math.random() > 0.5 ? '补气' : '祛湿'}，治${Math.random() > 0.5 ? '脾胃' : '肝肾'}疾病。`, source: '《新修本草》' },
      { period: '宋代 · 证类本草', quote: `${herbName}，气${Math.random() > 0.5 ? '香' : '平'}，味${Math.random() > 0.5 ? '甘微苦' : '苦涩'}。主治${Math.random() > 0.5 ? '虚劳' : '痰湿'}，${Math.random() > 0.5 ? '益气养血' : '清热解毒'}。`, source: '《证类本草》' },
      { period: '明代 · 本草纲目', quote: `${herbName}，${Math.random() > 0.5 ? '气温' : '气平'}，味${Math.random() > 0.5 ? '甘' : '苦'}。${Math.random() > 0.5 ? '补脾胃' : '清肝火'}，${Math.random() > 0.5 ? '润肺' : '益肾'}。${Math.random() > 0.5 ? '久服轻身延年。' : '常服强身健体。'}`, source: '《本草纲目》' },
      { period: '清代 · 本草从新', quote: `${herbName}，性${Math.random() > 0.5 ? '温' : '平'}，味${Math.random() > 0.5 ? '甘' : '淡'}。主治${Math.random() > 0.5 ? '虚损' : '湿热'}，${Math.random() > 0.5 ? '补中益气' : '清热解毒'}。`, source: '《本草从新》' },
      { period: '现代药理研究', quote: `${herbName}含有多种${Math.random() > 0.5 ? '生物碱' : '多糖'}和${Math.random() > 0.5 ? '黄酮类物质' : '挥发油'}，具有${Math.random() > 0.5 ? '抗炎' : '抗氧化'}、${Math.random() > 0.5 ? '提高免疫力' : '保肝'}作用。`, source: '《中药药理学》' },
    ];
    
    setHistoricalQuotes(mockQuotes);
    
    // 同时生成情感分析数据
    generateSentimentData(herbName);
    
    // 生成主题演化数据
    generateThemeEvolutionData(herbName);
  };
  
  // 生成情感分析数据
  const generateSentimentData = (herbName: string) => {
    // 模拟数据 - 实际应用中应该从NLP分析获取
    const mockSentimentData = [
      { period: '汉代', positive: 70 + Math.random() * 20, neutral: 20 + Math.random() * 10, negative: Math.random() * 10 },
      { period: '魏晋南北朝', positive: 60 + Math.random() * 20, neutral: 30 + Math.random() * 10, negative: 5 + Math.random() * 10 },
      { period: '隋唐', positive: 65 + Math.random() * 20, neutral: 25 + Math.random() * 10, negative: 5 + Math.random() * 10 },
      { period: '宋元', positive: 55 + Math.random() * 20, neutral: 30 + Math.random() * 10, negative: 10 + Math.random() * 15 },
      { period: '明代', positive: 75 + Math.random() * 15, neutral: 20 + Math.random() * 10, negative: Math.random() * 10 },
      { period: '清代', positive: 70 + Math.random() * 20, neutral: 20 + Math.random() * 15, negative: 5 + Math.random() * 10 },
      { period: '现代', positive: 80 + Math.random() * 15, neutral: 15 + Math.random() * 10, negative: Math.random() * 5 },
    ];
    
    // 确保总和为100
    mockSentimentData.forEach(item => {
      const total = item.positive + item.neutral + item.negative;
      item.positive = Math.round((item.positive / total) * 100);
      item.neutral = Math.round((item.neutral / total) * 100);
      item.negative = 100 - item.positive - item.neutral;
    });
    
    setSentimentData(mockSentimentData);
  };
  
  // 生成主题演化数据
  const generateThemeEvolutionData = (herbName: string) => {
    // 模拟数据 - 实际应用中应该从文本分析获取
    const mockThemeData = [
      { 
        theme: '药性理论', 
        periods: { 
          '古代': 80 + Math.random() * 20, 
          '中古': 70 + Math.random() * 20, 
          '近代': 60 + Math.random() * 20, 
          '现代': 40 + Math.random() * 20 
        } 
      },
      { 
        theme: '治疗应用', 
        periods: { 
          '古代': 60 + Math.random() * 20, 
          '中古': 70 + Math.random() * 20, 
          '近代': 80 + Math.random() * 20, 
          '现代': 70 + Math.random() * 20 
        } 
      },
      { 
        theme: '炮制方法', 
        periods: { 
          '古代': 30 + Math.random() * 20, 
          '中古': 50 + Math.random() * 20, 
          '近代': 60 + Math.random() * 20, 
          '现代': 50 + Math.random() * 20 
        } 
      },
      { 
        theme: '药理研究', 
        periods: { 
          '古代': 10 + Math.random() * 10, 
          '中古': 20 + Math.random() * 15, 
          '近代': 40 + Math.random() * 20, 
          '现代': 90 + Math.random() * 10 
        } 
      },
      { 
        theme: '临床效果', 
        periods: { 
          '古代': 50 + Math.random() * 20, 
          '中古': 60 + Math.random() * 20, 
          '近代': 70 + Math.random() * 20, 
          '现代': 85 + Math.random() * 15 
        } 
      }
    ];
    
    setThemeEvolutionData(mockThemeData);
  };
  
  // 文本分析视图模式切换
  const handleTextAnalysisModeChange = (mode: TextAnalysisMode) => {
    setTextAnalysisMode(mode);
  };
  
  // 处理药材搜索
  const handleHerbTextSearch = () => {
    if (searchText.trim()) {
      const matchedHerb = herbs.find(herb => herb.name.includes(searchText.trim()));
      if (matchedHerb) {
        searchHistoricalQuotes(matchedHerb.name);
      } else {
        // 如果没找到匹配的药材，可以提示用户
        searchHistoricalQuotes(searchText.trim());
      }
    }
  };
  
  // 处理输入变化
  const handleSearchInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchText(e.target.value);
  };

  // 渲染文本分析视图
  const renderTextualView = () => {
    return (
      <div className="textual-view">
        <div className="text-controls">
          <div className="view-mode-buttons">
            <h3>文本分析模式</h3>
            <div className="button-group">
              <button 
                className={textAnalysisMode === 'wordcloud' ? 'active' : ''}
                onClick={() => handleTextAnalysisModeChange('wordcloud')}
              >
                词云分析
              </button>
              <button 
                className={textAnalysisMode === 'historical' ? 'active' : ''}
                onClick={() => handleTextAnalysisModeChange('historical')}
              >
                历代评价
              </button>
              <button 
                className={textAnalysisMode === 'sentiment' ? 'active' : ''}
                onClick={() => handleTextAnalysisModeChange('sentiment')}
              >
                情感分析
              </button>
              <button 
                className={textAnalysisMode === 'evolution' ? 'active' : ''}
                onClick={() => handleTextAnalysisModeChange('evolution')}
              >
                主题演化
              </button>
            </div>
          </div>
          
          {textAnalysisMode !== 'wordcloud' && (
            <div className="herb-search-box">
              <h3>选择药材</h3>
              <div className="search-with-button">
                <input 
                  type="text" 
                  placeholder="输入药材名称..." 
                  value={searchText}
                  onChange={handleSearchInputChange}
                  onKeyPress={(e) => e.key === 'Enter' && handleHerbTextSearch()}
                />
                <button onClick={handleHerbTextSearch}>搜索</button>
              </div>
              <div className="quick-herb-buttons">
                <span>热门药材：</span>
                {['人参', '当归', '黄芪', '甘草', '川芎'].map(name => (
                  <button 
                    key={name} 
                    className="quick-herb-btn"
                    onClick={() => {
                      setSearchText(name);
                      searchHistoricalQuotes(name);
                    }}
                  >
                    {name}
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>
        
        <div className="text-content" ref={textAnalysisRef}>
          {/* 词云视图 */}
          {textAnalysisMode === 'wordcloud' && (
            <div className="wordcloud-container">
              <h2>本草药材描述词频分析</h2>
              <p className="chart-description">基于所有药材描述文本的高频词汇可视化</p>
              
              <div className="wordcloud-display">
                {wordCloudData.length > 0 ? (
                  <div className="cloud-wrapper">
                    {wordCloudData.slice(0, 50).map((item, index) => (
                      <span
                        key={index}
                        className="cloud-word"
                        style={{
                          fontSize: `${Math.max(14, Math.min(48, 14 + item.value * 2))}px`,
                          fontWeight: item.value > 3 ? 'bold' : 'normal',
                          opacity: 0.7 + (item.value / 20),
                          transform: `rotate(${Math.random() > 0.5 ? 1 : -1 * Math.random() * 20}deg)`
                        }}
                      >
                        {item.text}
                      </span>
                    ))}
                  </div>
                ) : (
                  <div className="loading-cloud">正在生成词云...</div>
                )}
              </div>
              
              <div className="wordcloud-stats">
                <h3>高频词汇统计</h3>
                <div className="word-stats-grid">
                  {wordCloudData.slice(0, 10).map((item, index) => (
                    <div key={index} className="word-stat-item">
                      <span className="word-text">{item.text}</span>
                      <div className="word-bar-wrapper">
                        <div 
                          className="word-bar" 
                          style={{ 
                            width: `${Math.min(100, item.value * 5)}%`,
                            backgroundColor: `hsl(${index * 36}, 70%, 60%)`
                          }}
                        ></div>
                      </div>
                      <span className="word-count">{item.value}</span>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          )}
          
          {/* 历代评价视图 */}
          {textAnalysisMode === 'historical' && (
            <div className="historical-container">
              <h2>{selectedHerbForText ? `${selectedHerbForText}的历代评价` : '药材历代评价'}</h2>
              <p className="chart-description">展示历代医学文献中对药材的记载与评价</p>
              
              {selectedHerbForText ? (
                <div className="historical-quotes">
                  <div className="timeline">
                    {historicalQuotes.map((quote, index) => (
                      <div key={index} className="timeline-item">
                        <div className="timeline-marker"></div>
                        <div className="timeline-content">
                          <h3 className="period-title">{quote.period}</h3>
                          <div className="quote-content">
                            <p className="quote-text">{quote.quote}</p>
                            <p className="quote-source">—— {quote.source}</p>
                          </div>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              ) : (
                <div className="no-herb-selected-for-text">
                  <p>请在上方输入或选择药材名称</p>
                </div>
              )}
            </div>
          )}
          
          {/* 情感分析视图 */}
          {textAnalysisMode === 'sentiment' && (
            <div className="sentiment-container">
              <h2>{selectedHerbForText ? `${selectedHerbForText}的情感倾向分析` : '药材情感倾向分析'}</h2>
              <p className="chart-description">分析历代文献中对药材记载的情感倾向变化</p>
              
              {selectedHerbForText ? (
                <div className="sentiment-content">
                  <div className="sentiment-chart">
                    <div className="chart-labels">
                      <div className="y-axis-label">情感倾向比例 (%)</div>
                      <div className="x-axis-label">历史时期</div>
                    </div>
                    
                    <div className="stacked-bars-container">
                      {sentimentData.map((data, index) => (
                        <div key={index} className="stacked-bar-group">
                          <div className="stacked-bar">
                            <div 
                              className="bar-segment positive" 
                              style={{ height: `${data.positive}%` }}
                              title={`正面评价: ${data.positive}%`}
                            ></div>
                            <div 
                              className="bar-segment neutral" 
                              style={{ height: `${data.neutral}%` }}
                              title={`中性评价: ${data.neutral}%`}
                            ></div>
                            <div 
                              className="bar-segment negative" 
                              style={{ height: `${data.negative}%` }}
                              title={`负面评价: ${data.negative}%`}
                            ></div>
                          </div>
                          <div className="period-label">{data.period}</div>
                        </div>
                      ))}
                    </div>
                  </div>
                  
                  <div className="sentiment-legend">
                    <div className="legend-item">
                      <span className="legend-color positive"></span>
                      <span className="legend-label">正面评价</span>
                    </div>
                    <div className="legend-item">
                      <span className="legend-color neutral"></span>
                      <span className="legend-label">中性评价</span>
                    </div>
                    <div className="legend-item">
                      <span className="legend-color negative"></span>
                      <span className="legend-label">负面评价</span>
                    </div>
                  </div>
                  
                  <div className="sentiment-analysis">
                    <h3>情感倾向分析</h3>
                    <p>
                      根据历代医学文献对<strong>{selectedHerbForText}</strong>的记载分析，该药材整体评价偏向
                      <strong>{sentimentData.reduce((acc, curr) => acc + curr.positive, 0) / sentimentData.length > 65 ? '非常正面' : sentimentData.reduce((acc, curr) => acc + curr.positive, 0) / sentimentData.length > 50 ? '偏正面' : '中性'}</strong>。
                      {sentimentData[sentimentData.length - 1].positive > sentimentData[0].positive ? 
                        '近代对其评价较古代更为积极。' : 
                        sentimentData[sentimentData.length - 1].positive < sentimentData[0].positive ? 
                        '古代对其评价较近代更为积极。' : 
                        '其评价在历代保持相对稳定。'
                      }
                    </p>
                    <p>
                      在{sentimentData.reduce((max, obj, i) => obj.positive > sentimentData[max].positive ? i : max, 0)}时期，
                      该药材获得了最积极的评价，主要赞誉其
                      {Math.random() > 0.5 ? '药效显著' : Math.random() > 0.5 ? '应用广泛' : '品质优良'}。
                      {sentimentData.some(data => data.negative > 10) ? 
                        `而在部分时期也有少量负面评价，主要关注其${Math.random() > 0.5 ? '副作用' : Math.random() > 0.5 ? '采集难度' : '保存问题'}。` : 
                        '历代文献中几乎没有明显的负面评价。'
                      }
                    </p>
                  </div>
                </div>
              ) : (
                <div className="no-herb-selected-for-text">
                  <p>请在上方输入或选择药材名称</p>
                </div>
              )}
            </div>
          )}
          
          {/* 主题演化视图 */}
          {textAnalysisMode === 'evolution' && (
            <div className="evolution-container">
              <h2>{selectedHerbForText ? `${selectedHerbForText}的主题演化分析` : '药材主题演化分析'}</h2>
              <p className="chart-description">展示关于药材记载的主题在不同历史时期的变化</p>
              
              {selectedHerbForText ? (
                <div className="evolution-content">
                  <div className="evolution-chart">
                    <div className="chart-header">
                      <div className="time-periods">
                        <div className="time-label">古代</div>
                        <div className="time-label">中古</div>
                        <div className="time-label">近代</div>
                        <div className="time-label">现代</div>
                      </div>
                    </div>
                    
                    <div className="themes-container">
                      {themeEvolutionData.map((themeData, index) => (
                        <div key={index} className="theme-row">
                          <div className="theme-label">{themeData.theme}</div>
                          <div className="theme-evolution">
                            {(['古代', '中古', '近代', '现代'] as const).map(period => (
                              <div 
                                key={period} 
                                className="evolution-segment"
                                style={{ 
                                  backgroundColor: `rgba(141, 77, 59, ${((themeData.periods?.[period] ?? 0) / 100)})`,
                                  height: `${Math.max(20, ((themeData.periods?.[period] ?? 0) / 2))}px`,
                                  width: `${Math.max(20, ((themeData.periods?.[period] ?? 0) / 2))}px`,
                                  borderRadius: '50%',
                                }}
                                title={`${period}: ${themeData.periods?.[period] ?? 0}%`}
                              ></div>
                            ))}
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                  
                  <div className="evolution-legend">
                    <span>关注度：</span>
                    <div className="bubble-legend">
                      <div className="bubble-item">
                        <div className="bubble low"></div>
                        <span>低</span>
                      </div>
                      <div className="bubble-item">
                        <div className="bubble medium"></div>
                        <span>中</span>
                      </div>
                      <div className="bubble-item">
                        <div className="bubble high"></div>
                        <span>高</span>
                      </div>
                    </div>
                  </div>
                  
                  <div className="evolution-analysis">
                    <h3>主题演化趋势分析</h3>
                    <p>
                      从古至今，<strong>{selectedHerbForText}</strong>的相关记载主题发生了明显变化。
                      在古代，主要关注其
                      {(() => {
                        const data = themeEvolutionData.length > 0 ? themeEvolutionData : DEFAULT_THEME_DATA;
                        if (data[0]?.periods?.['古代'] > 70) return '药性理论';
                        if (data[1]?.periods?.['古代'] > 70) return '治疗应用';
                        if (data[2]?.periods?.['古代'] > 70) return '炮制方法';
                        return '临床效果';
                      })()}；
                      而到了现代，则更注重
                      {(() => {
                        const data = themeEvolutionData.length > 0 ? themeEvolutionData : DEFAULT_THEME_DATA;
                        if (data[3]?.periods?.['现代'] > 70) return '药理研究';
                        if (data[4]?.periods?.['现代'] > 70) return '临床效果';
                        if (data[1]?.periods?.['现代'] > 70) return '治疗应用';
                        return '药性理论';
                      })()}。
                    </p>
                    <p>
                      特别值得注意的是，
                      {(() => {
                        const data = themeEvolutionData.length > 0 ? themeEvolutionData : DEFAULT_THEME_DATA;
                        const ancientData3 = data[3]?.periods?.['古代'] ?? 0;
                        const modernData3 = data[3]?.periods?.['现代'] ?? 0;
                        const diff3 = modernData3 - ancientData3;
                        
                        if (diff3 > 60) {
                          return '药理研究的关注度从古代到现代有了显著提升，反映了现代科学方法对传统中药研究的影响。';
                        }
                        
                        const ancientData0 = data[0]?.periods?.['古代'] ?? 0;
                        const modernData0 = data[0]?.periods?.['现代'] ?? 0;
                        const diff0 = ancientData0 - modernData0;
                        
                        if (diff0 > 30) {
                          return '药性理论的讨论在古代文献中占比较高，而现代则有所减少，体现了研究重点的转变。';
                        }
                        
                        return '治疗应用的讨论在各个时期都保持较高关注度，显示了该药材的持久医用价值。';
                      })()}
                    </p>
                  </div>
                </div>
              ) : (
                <div className="no-herb-selected-for-text">
                  <p>请在上方输入或选择药材名称</p>
                </div>
              )}
            </div>
          )}
        </div>
      </div>
    );
  };

  // 根据当前视图渲染内容
  const renderCurrentView = () => {
    switch (activeView) {
      case 'overview':
        return renderOverviewView();
      case 'classification':
        return renderClassificationView();
      case 'properties':
        return renderPropertiesView();
      case 'relations':
        return renderRelationsView();
      case 'geographic':
        return renderGeographicView();
      case 'textual':
        return renderTextualView();
      default:
        return renderOverviewView();
    }
  };

  // 渲染顶部导航
  const renderNavigation = () => {
    return (
      <div className="dashboard-nav">
        <div className="nav-logo">
          <h1>本草纲目</h1>
          <span className="subtitle">中药智能查询系统</span>
        </div>
        <div className="nav-menu">
          <button 
            className={activeView === 'overview' ? 'active' : ''}
            onClick={() => setActiveView('overview')}
          >
            总览
          </button>
          <button 
            className={activeView === 'classification' ? 'active' : ''}
            onClick={() => setActiveView('classification')}
          >
            分类系统
          </button>
          <button 
            className={activeView === 'properties' ? 'active' : ''}
            onClick={() => setActiveView('properties')}
          >
            属性分析
          </button>
          <button 
            className={activeView === 'relations' ? 'active' : ''}
            onClick={() => setActiveView('relations')}
          >
            关联网络
          </button>
          <button 
            className={activeView === 'geographic' ? 'active' : ''}
            onClick={() => setActiveView('geographic')}
          >
            地理历史
          </button>
          <button 
            className={activeView === 'textual' ? 'active' : ''}
            onClick={() => setActiveView('textual')}
          >
            文本分析
          </button>
        </div>
        <div className="nav-actions">
          <div className="search-box">
            <input 
              type="text" 
              placeholder="搜索药材..." 
              value={filterOptions.keyword}
              onChange={handleKeywordChange}
            />
            <button className="search-button">
              <span className="search-icon">🔍</span>
            </button>
          </div>
        </div>
      </div>
    );
  };

  useEffect(() => {
    if (initialView) {
      setActiveView(initialView);
    }
  }, [initialView]);

  if (isLoading) {
    return (
      <div className="loading">
        <div className="loading-spinner"></div>
        <p>正在加载数据...</p>
      </div>
    );
  }

  return (
    <div className="dashboard-container">
      {renderNavigation()}

      <div className="dashboard-content">
        {renderCurrentView()}
      </div>
    </div>
  );
}; 